package twoD.IsoPfem.math;

/**
 * class provide Gauss points and weight for integration over reference triangle
 * using area coordinates
 * 
 * @author Bui Hoang Giang
 */
public final class GaussPointsT {

	private static void checkP(int p) {
		if (p > MAX_P) {
			throw new IllegalArgumentException(
					"Order exceed allowance provided for Gauss quadrature: "
							+ p);
		}
	}

	/**
	 * Returns the i-th Gauss point for a Gauss-Legendre quadrature with p is
	 * degree of Gauss integration on the triangle domain.
	 * 
	 * @param p
	 *            the order of integration.
	 * @param i
	 *            index of the gauss point.
	 * @return the gauss point
	 */
	public static double[] getPoint(int p, int i) {
		checkP(p);
		return new double[] { GQW[p - 1][i][0], GQW[p - 1][i][1],
				GQW[p - 1][i][2] };
	}

	/**
	 * Returns the weighting factor of the i-th Gauss point for a Gauss-Legendre
	 * quadrature with p is degree of Gauss integration on the interval [-1, 1].
	 * 
	 * @param p
	 *            the order of integration.
	 * @param i
	 *            index of the gauss point.
	 * @return the weighting factor for the corresponding gauss point
	 */
	public static double getWeight(int p, int i) {
		checkP(p);
		return GQW[p - 1][i][3];
	}

	/**
	 * @param p
	 *            the order of integration
	 * 
	 * @return the number of integration points correspond to the order
	 */
	public static int getNumOfIntegrationPoints(int p) {
		checkP(p);
		return GQW[p - 1].length;
	}

	private static final double[][][] GQW = {
			{ { 1.0 / 3, 1.0 / 3, 1.0 / 3, 1.0 } },
			 { { 0, 0.5, 0.5, 1.0 / 3 }, { 0.5, 0, 0.5, 1.0 / 3 },
			 { 0.5, 0.5, 0, 1.0 / 3 } },
			// { { 2.0 / 3, 1.0 / 6, 1.0 / 6, 1.0 / 3 },
			// { 1.0 / 6, 2.0 / 3, 1.0 / 6, 1.0 / 3 },
			// { 1.0 / 6, 1.0 / 6, 2.0 / 3, 1.0 / 3 } },
			{
					{ 0.108103018168070, 0.445948490915965, 0.445948490915965,
							0.223381589678011 },
					{ 0.445948490915965, 0.108103018168070, 0.445948490915965,
							0.223381589678011 },
					{ 0.445948490915965, 0.445948490915965, 0.108103018168070,
							0.223381589678011 },
					{ 0.816847572980459, 0.0915762135097707,
							0.0915762135097707, 0.109951743655322 },
					{ 0.0915762135097707, 0.816847572980459,
							0.0915762135097707, 0.109951743655322 },
					{ 0.0915762135097707, 0.0915762135097707,
							0.816847572980459, 0.109951743655322 } },

			{
					{ 0.797426985353087, 0.101286507323456, 0.101286507323456,
							0.125939180544827 },
					{ 0.101286507323456, 0.797426985353087, 0.101286507323456,
							0.125939180544827 },
					{ 0.101286507323456, 0.101286507323456, 0.797426985353087,
							0.125939180544827 },
					{ 0.0597158717897699, 0.470142064105115, 0.470142064105115,
							0.132394152788506 },
					{ 0.470142064105115, 0.0597158717897699, 0.470142064105115,
							0.132394152788506 },
					{ 0.470142064105115, 0.470142064105115, 0.0597158717897699,
							0.132394152788506 },
					{ 0.333333333333333, 0.333333333333333, 0.333333333333333,
							0.225000000000000 } } };

	/** The maximum order of Gauss integration support by this class */
	public static final int MAX_P = GQW.length;

}
